/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bakenote.core;

import org.apache.pivot.collections.ArrayList;
import org.apache.pivot.collections.List;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

/**
 *
 * @author lello
 */
public class Procedure {

	private Duration duration = null;
    private String description = "";
    private List<ElementalProcedure> elementalProcedureList = new ArrayList<ElementalProcedure>();

    public Procedure() {}

	public Procedure(Duration d) {
		duration = d;
	}

    public Procedure(Procedure p) {
        this.duration = p.getDuration();
        this.description = p.getDescription();
        this.elementalProcedureList = p.getElementalProcedureList();
    }

    public void add(ElementalProcedure elementalProcedure) {
        elementalProcedureList.add(elementalProcedure);
    }
	public Procedure(Duration d, String s) {
		duration = d;
		description = s;
	}

	public void setDescription(String d) {
		description = d;
	}

	public Duration getDuration() {
        try {
            duration = DatatypeFactory.newInstance().newDuration("PT0M");
            for (ElementalProcedure e: elementalProcedureList) {
                duration = e.getDuration().add(duration);
            }
        } catch (DatatypeConfigurationException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
		return duration;
	}

	public String getDescription() {
		return description;
	}

    public void writeXML() {
        // save the procedure in a XML file
    }

    public void readXML(String xmlString) {

        // Create main document
        DocumentBuilderFactory docFac = DocumentBuilderFactory.newInstance();
        DocumentBuilder docB = null;
        try {
            docB = docFac.newDocumentBuilder();
            Document doc = docB.parse(new InputSource( new StringReader(xmlString)));
            Element element = doc.getDocumentElement();
            NodeList nodeList = element.getElementsByTagName("step");
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node stepNode = nodeList.item(i);
                if (stepNode instanceof Element) {
                    String description = ((Element)stepNode).getElementsByTagName("description").item(0).getTextContent();
                    String time  = ((Element)stepNode).getElementsByTagName("time").item(0).getTextContent();
                    Duration duration = (DatatypeFactory.newInstance().newDuration(time));
                    this.elementalProcedureList.add(new ElementalProcedure(duration,description));
                }
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DatatypeConfigurationException e) {
            e.printStackTrace();
        }

        //return this;
    }

    public ElementalProcedure getStep(int i) {
        return elementalProcedureList.get(i);
    }

    public List<ElementalProcedure> getElementalProcedureList() {
        return elementalProcedureList;
    }

    public String getXML() {

        // Create main document
        DocumentBuilderFactory docFac = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = null;
        try {
            documentBuilder = docFac.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        Document doc = documentBuilder.newDocument();

        Element procedureElement = doc.createElement("procedure");
        for (int i = 0; i < this.getElementalProcedureList().getLength(); i++) {
            Element stepElement = doc.createElement("step");
            Element timeElement = doc.createElement("time");
            Text textNode = doc.createTextNode(this.getStep(i).getDuration().toString());
            timeElement.appendChild(textNode);
            Element descriptionElement = doc.createElement("description");
            textNode = doc.createTextNode(this.getStep(i).getDescription());
            descriptionElement.appendChild(textNode);
            stepElement.appendChild(timeElement);
            stepElement.appendChild(descriptionElement);
            procedureElement.appendChild(stepElement);
        }
        doc.appendChild(procedureElement);

        // Write the procedure to a stringWriter and apply indentation
        Transformer transformer = null;
        try {
            transformer = TransformerFactory.newInstance().newTransformer();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        }
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");

        StringWriter stringWriter = new StringWriter();
        StreamResult result = new StreamResult(stringWriter);
        Source source = new DOMSource(doc);
        try {
            transformer.transform(source,result);
            //System.out.println("result " + stringWriter.toString());
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        // Save the xml element to a file
        return stringWriter.toString();
    }

}
